package com.kangjia.model.m1.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kangjia.jasckson.DataMapper;
import com.kangjia.model.m0.entity.Menu;
import com.kangjia.model.m0.service.MenuService;
import com.kangjia.model.m1.entity.Employee;
import com.kangjia.model.m1.service.EmployeeService;
import com.kangjia.model.service.CookieService;
import com.kangjia.response.AbstractResponse;
import com.kangjia.response.ErrorResponse;
import com.kangjia.response.ObjectResponse;
import com.kangjia.response.SuccessResponse;
import com.kangjia.type.Md5;
import com.kangjia.util.NetworkUtil;
import com.kangjia.util.RsaUtils;
import com.kangjia.util.VerifyCodeUtils;

import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Controller
@Slf4j
public class IndexController {

	@Value("${rsa.primity.key}")
	private String rsaprk;
	@Autowired
	private EmployeeService employeeService;
	@Autowired
	protected JedisPool jedisPool;
	@Autowired
	private CookieService cookieService;
	@Autowired
	private MenuService menuService;

	/**
	 * 系统默认访问项,生成cookie,header
	 * 
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/a/index")
	@ResponseBody
	public AbstractResponse index(HttpServletRequest request, HttpServletResponse response) {
		String ip = null;
		try {
			ip = NetworkUtil.getIpAddress(request);
		} catch (IOException e) {
			return new ErrorResponse("地址解析错误");
		}
		String encrypt = cookieService.encrypt(ip);
		return new SuccessResponse(encrypt);
	}

	@RequestMapping(value = "/a/img")
	@ResponseBody
	public AbstractResponse createImg(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		response.setContentType("image/jpeg");
		String encrypt = request.getHeader("HWBK");
		if (StringUtils.isBlank(encrypt)) {
			return new ErrorResponse("系统访问标识失效,刷新界面");
		}
		String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
		Jedis jedis = jedisPool.getResource();
		try {
			String key = encrypt + ".code";
			jedis.set(key.toLowerCase(), verifyCode);
			jedis.expire(key, 60);
		} finally {
			jedis.close();
		}
		int w = 150, h = 50;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			VerifyCodeUtils.outputImage(w, h, baos, verifyCode);
		} catch (IOException e) {
			log.error("生成验证码图片错误", e);
			return new ErrorResponse("生成验证码图片错误");
		} finally {
			try {
				baos.close();
			} catch (IOException e) {
				log.error("ByteArrayOutputStream关闭流异常", e);
			}
		}
		return new SuccessResponse("data:image/gif;base64," + Base64Utils.encodeToString(baos.toByteArray()));
	}

	@RequestMapping(value = "/a/login", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ResponseBody
	public AbstractResponse login(@RequestBody Employee entity, HttpServletRequest request,
			HttpServletResponse response) {
		Jedis jedis = jedisPool.getResource();
		try {
			String encrypt = request.getHeader("HWBK");
			if (StringUtils.isBlank(encrypt)) {
				log.error("'HWBK'失效");
				return new ErrorResponse("系统访问标识失效,刷新界面");
			}
			String key = encrypt + ".code";
			String code = jedis.get(key.toLowerCase());
			if (StringUtils.isBlank(code)) {
				return new ErrorResponse("验证码失效");
			}
			if (!code.equalsIgnoreCase(entity.getCode())) {
				return new ErrorResponse("验证码错误");
			}
			jedis.del(key);
			String login = null;
			String pass = null;
			try {
				login = new String(RsaUtils.decryptByPrivateKey(RsaUtils.decryptBASE64(entity.getLogin()), rsaprk));
				pass = new String(RsaUtils.decryptByPrivateKey(RsaUtils.decryptBASE64(entity.getPass()), rsaprk));
			} catch (Exception e) {
				return new ErrorResponse("系统错误,解密失败.");
			}
			Employee employee = employeeService.queryByLogin(login);
			if (employee == null) {
				return new ErrorResponse("账号不存在");
			}
			if (!Md5.encrypt(pass).equals(employee.getPass())) {
				return new ErrorResponse("密码错误");
			}
			String json = employeeService.create(employee);
			jedis.set(encrypt, json);
			jedis.expire(encrypt, 3600);
			return new ObjectResponse<>(employee);
		} finally {
			jedis.close();
		}
	}

	@RequestMapping(value = "/b/logout", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@ResponseBody
	public AbstractResponse logout(@RequestBody Employee entity, HttpServletRequest request,
			HttpServletResponse response) {
		String encrypt = request.getHeader("HWBK");
		if (StringUtils.isNotBlank(encrypt)) {
			Jedis jedis = jedisPool.getResource();
			try {
				jedis.del(encrypt);
			} finally {
				jedis.close();
			}
		}
		return new SuccessResponse("已登出");
	}

	@RequestMapping(value = "/b/menu")
	@ResponseBody
	public Menu tree(@RequestBody Menu menu, HttpServletRequest request) {
		String encrypt = request.getHeader("HWBK");
		if (StringUtils.isNotBlank(encrypt)) {
			Jedis jedis = jedisPool.getResource();
			String json = null;
			try {
				json = jedis.get(encrypt);
			} catch (Exception e) {
				log.error("", e);
			} finally {
				jedis.close();
			}
			if (StringUtils.isNotBlank(encrypt)) {
				Employee employee = DataMapper.read(json, Employee.class);
				String[] ms = employee.getAuthority().split(",");
				List<Menu> menus = menuService.query();
				return menuService.createRoot(menuService.filter(menus, ms));
			}
		}
		return null;
	}
}
